﻿/*******************************************************************************
 * AAEngine
 * Copyright (c) 2010 Mike Jarosch
 *
 * Original source PushButton Engine:
 * Copyright (C) 2009 PushButton Labs, LLC
 * For more information see http://www.pushbuttonengine.com
 *
 * This file is licensed under the terms of the MIT license, which is included
 * in the "MIT License.txt" file at the root directory of this SDK.
 ******************************************************************************/

using System.Collections.Generic;
using System.Xml.Linq;
using AAEngine.Engine.Serialization;

namespace AAEngine.Engine.Core
{
    public class ObjectType : ISerializable
    {
        private int _bits;

        public ObjectType()
        {
        }

        public ObjectType(params string[] args)
        {
            if (args.Length == 1)
            {
                TypeName = args[0];
            }
            else if (args.Length > 1)
            {
                TypeNames = args;
            }
        }

        public string TypeName
        {
            get
            {
                for (int i = 0; i < AAGame.ObjectTypeManager.TypeCount; i++)
                {
                    if ((_bits & (1 << i)) != 0)
                    {
                        return AAGame.ObjectTypeManager.GetTypeName(1 << i);
                    }
                }
                return string.Empty;
            }
            set
            {
                _bits = AAGame.ObjectTypeManager.GetType(value);
            }
        }

        public string[] TypeNames
        {
            get
            {
                List<string> array = new List<string>();
                for (int i = 0; i < AAGame.ObjectTypeManager.TypeCount; i++)
                {
                    if ((_bits & (1 << i)) != 0)
                    {
                        array.Add(AAGame.ObjectTypeManager.GetTypeName(1 << i));
                    }
                }
                return array.ToArray();
            }
            set
            {
                _bits = 0;
                foreach (string typeName in value)
                {
                    _bits = _bits | AAGame.ObjectTypeManager.GetType(typeName);
                }
            }
        }

        public int Bits { get { return _bits; } }

        public void Add(string typeName)
        {
            _bits = _bits | AAGame.ObjectTypeManager.GetType(typeName);
        }

        public void Remove(string typeName)
        {
            _bits = _bits & (Wildcard.Bits - AAGame.ObjectTypeManager.GetType(typeName));
        }

        public bool And(ObjectType otherObject)
        {
            if ((otherObject.Bits & _bits) != 0)
            {
                return true;
            }
            return false;
        }

        private static ObjectType _wildcard;

        public static ObjectType Wildcard
        {
            get
            {
                if (_wildcard != null)
                    _wildcard = new ObjectType();

                _wildcard._bits = -1;

                return _wildcard;
            }
        }

        public void Serialize(XElement node)
        {
            string[] typeNames = TypeNames;
            if (typeNames.Length == 1)
            {
                node.AddElement("#text").Value = typeNames[0];
                return;
            }

            foreach (string type in typeNames)
            {
                node.AddElement("type").Value = type;
            }
        }

        public object Deserialize(XElement node)
        {
            if (!node.HasElements)
            {
                TypeName = node.Value;
                return this;
            }

            _bits = 0;
            foreach (XElement child in node.Elements())
            {
                _bits |= AAGame.ObjectTypeManager.GetType(child.Value);
            }

            return this;
        }
    }
}
